require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-ignition-ethers");
const fs = require('fs');
const path = require('path');

// const { ethers } = require("hardhat");

function randomRecord(amount) {
  // 预定义姓名字典
  const names = ["张三", "李四", "王五", "赵六", "钱七", "孙八", "周九", "吴十"];
  // 医疗类型描述
  // const medicalTypes = ["门诊", "住院", "检查", "手术", "急诊"];

  const records = [];
  for (let i = 0; i < amount; i++) {
    // 生成随机身份证号 (18位)
    const idNumber = '123456' +
      Math.floor(Math.random() * 1000000000000).toString().padStart(12, '0');

    // 生成随机日期 (2023-2025年之间)
    const year = 2023 + Math.floor(Math.random() * 3);
    const month = 1 + Math.floor(Math.random() * 12);
    const day = 1 + Math.floor(Math.random() * 28);
    const date = `${year}-${month}-${day}`;

    records.push({
      name: names[Math.floor(Math.random() * names.length)],
      idNumber: idNumber,
      date: date,
      type: Math.floor(Math.random() * 5), // 0-4随机类型
      amount: ethers.parseEther((5 + Math.random() * 10).toFixed(2)), // 5-15 ETH随机金额
      desc: "" // 空字符串
    });
  }
  return records;
}

let roleSystem, medicalRecord;

let roleManager, recordRegistry, signatureClaim;

async function compileAll(forced) {
  if (forced) {
    console.log("Forced to compile all contracts...");
    await hre.run("compile --force");
  } else {
    console.log("Checking if contracts need to be compiled...");
    await hre.run("compile");
  }

  // console.log(`Finishi compiled.`);
  console.log("Trying to write ABI to shared/abis...");

  try {
    const abiDir = path.join(__dirname, 'shared/abis');

    const artifactPaths = await hre.artifacts.getArtifactPaths();
    console.log("artifactPaths:", artifactPaths);
    for (const artifactPath of artifactPaths) {
      const artifact = require(artifactPath);
      const contractName = path.basename(artifactPath, '.json');;

      fs.writeFileSync(
        path.join(abiDir, `${contractName}.json`),
        JSON.stringify(
          artifact.abi, null, 2
        )
      )
      console.log(`ABIs ${contractName} exported to ./abis directory`);
    }
  } catch (err) {
    console.error("Error writing ABI:", err);
  }
}

async function deployContracts() {
  const [deployer] = await ethers.getSigners();
  console.log(`Deploying contract address: ${deployer.address}`);

  const RoleManager = await ethers.getContractFactory("RoleManager");
  const RecordRegistry = await ethers.getContractFactory("RecordRegistry");
  const SignatureClaim = await ethers.getContractFactory("SignatureClaim");

  roleManager = await RoleManager.deploy();
  await roleManager.waitForDeployment();
  const roleManagerAddr = await roleManager.getAddress();
  console.log("成功部署RoleManager:", roleManagerAddr);


  recordRegistry = await RecordRegistry.deploy(roleManager.getAddress());
  await recordRegistry.waitForDeployment();
  const recordRegistryAddr = await recordRegistry.getAddress();
  console.log("成功部署RecordRegistry:", recordRegistryAddr);

  signatureClaim = await SignatureClaim.deploy(recordRegistryAddr, roleManagerAddr,
    { value: ethers.parseEther("9990") });
  await signatureClaim.waitForDeployment();
  const signatureClaimAddr = await signatureClaim.getAddress();
  console.log("成功部署SignatureClaim:", signatureClaimAddr);

  roleManager.connect(deployer).assignRole(
    signatureClaimAddr,
    5 // 3对应SignatureClaim角色
  )

  roleManager.connect(deployer).assignRole(
    recordRegistryAddr,
    4 // 4对应RecordRegistry角色
  )

  // 更新环境变量
  // let envContent = fs.existsSync('.env') ? fs.readFileSync('.env', 'utf8') : '';

  // 写入合约地址到JSON文件
  const addressDir = path.join(__dirname, 'shared');
  if (!fs.existsSync(addressDir)) {
    fs.mkdirSync(addressDir, { recursive: true });
  }

  const contractAddresses = {
    RoleManager: roleManagerAddr,
    RecordRegistry: recordRegistryAddr,
    SignatureClaim: signatureClaimAddr
  };

  fs.writeFileSync(
    path.join(addressDir, 'contract-address.json'),
    JSON.stringify(contractAddresses, null, 2)
  );
  console.log('合约地址已写入 shared/contract-address.json');
}

task("deploy-and-start", "Deploy contract and start node", async () => {
  await deployContracts();
  // 启动节点
  await hre.run("node");
});

task("compileAll", "Compile contracts", async (args) => {
  const { abi } = args;

  if (abi) {
    // 导出ABI
    await compileAll(true);
  } else {
    await compileAll();
  }
})
  .addFlag(
    "abi",
    "Export ABI to shared/abis"
  )

task("dev", "Start a local node", async (args) => {
  const { testrecord, assignrole } = args;
  // console.log(args);

  await deployContracts();

  [admin, patient, hospital, lab, other] = await ethers.getSigners();

  if (assignrole) {
    // 设置患者角色
    await roleManager.connect(admin).assignRole(
      patient.address,
      1 // 1对应Patient角色
    );
    console.log('Role assigned to patient:', patient.address)

    // 设置医院角色
    await roleManager.connect(admin).assignRole(
      hospital.address,
      2 // 2对应Hospital角色
    );
    console.log('Role assigned to hospital:', hospital.address)
  }

  if (testrecord) {
    // 运行测试
    const testRecords = randomRecord(6);

    for (const record of testRecords) {
      await recordRegistry.connect(hospital).createRecord(
        record.name,
        record.idNumber,
        record.date,
        record.type,
        record.amount,
        record.desc
      );
      console.log(`Created record for ${record.name} (ID: ${record.idNumber})`);
    }

    console.log("5 random records created by hospital:", hospital.address);
  }
  // 启动节点
  await hre.run("node");
}).addFlag(
  "testrecord",
  "Run tests in deployment"
).addFlag(
  "assignrole",
  "Assign role to address"
);

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.28",
  allowUnlimitedContractSize: true,
  networks: {
    hardhat: {
      accounts: {
        count: 6 // 只生成6个测试账户
      },
      gas: 80000000, // 默认gas限制
      blockGasLimit: 80000000, // 区块gas限制
      // loggingEnabled: true, // 启用日志记录
    },
    localhost: {
      url: "http://127.0.0.1:8545",
      // 预配置账户（第一个地址即为管理员）
      accounts: [
        "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", // 管理员私钥（地址：0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266）
        "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", // 其他测试账户
        "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a",
        "0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6",
        "0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a",
      ],
    },
  },
  scripts: {
    post: {
      node: "hardhat run scripts/deploy.cjs --network localhost"
    }
  },
  gasReporter: {
    enabled: true,
    currency: "USD",
    gasPrice: 21 // Gwei
  }
};
